JavaScriptã®éåæã³ã³ããã¹ããšãªã¯ãšã¹ãã¹ã³ãŒã倿°ã®å¹æçãªç®¡çæ¹æ³ãæ¢ããŸããAsyncLocalStorageã®ãŠãŒã¹ã±ãŒã¹ããã¹ããã©ã¯ãã£ã¹ãä»£æ¿æ¡ã«ã€ããŠè§£èª¬ããŸãã
JavaScriptã®éåæã³ã³ããã¹ãïŒãªã¯ãšã¹ãã¹ã³ãŒã倿°ã®ç®¡ç
éåæããã°ã©ãã³ã°ã¯ãçŸä»£ã®JavaScriptéçºã®åºç€ã§ãããç¹ã«Node.jsã®ãããªãã³ããããã³ã°I/Oãããã©ãŒãã³ã¹ã«äžå¯æ¬ ãªç°å¢ã§ã¯éèŠã§ããããããéåææäœããŸããã§ã³ã³ããã¹ãã管çããããšã¯å°é£ãªå ŽåããããŸããããã§ãJavaScriptã®éåæã³ã³ããã¹ããå
·äœçã«ã¯AsyncLocalStorage
ã圹ç«ã¡ãŸãã
éåæã³ã³ããã¹ããšã¯äœãïŒ
éåæã³ã³ããã¹ããšã¯ããã®ã©ã€ããµã€ã¯ã«å šäœã§æç¶ããéåææäœã«ããŒã¿ãé¢é£ä»ããæ©èœã®ããšã§ããããã¯ãè€æ°ã®éåæåŒã³åºãã«ããã£ãŠãªã¯ãšã¹ãã¹ã³ãŒãã®æ å ±ïŒäŸïŒãŠãŒã¶ãŒIDããªã¯ãšã¹ãIDããã¬ãŒã·ã³ã°æ å ±ïŒãç¶æããå¿ èŠãããã·ããªãªã§äžå¯æ¬ ã§ããé©åãªã³ã³ããã¹ã管çããªããã°ããããã°ããã®ã³ã°ãã»ãã¥ãªãã£ãèããå°é£ã«ãªãå¯èœæ§ããããŸãã
éåææäœã«ãããã³ã³ããã¹ãç¶æã®èª²é¡
颿°åŒã³åºããéããŠå€æ°ãæç€ºçã«æž¡ããšãã£ããåŸæ¥ã®ã³ã³ããã¹ã管çã¢ãããŒãã¯ãéåæã³ãŒãã®è€éããå¢ãã«ã€ããŠãç ©éã§ãšã©ãŒãçºçãããããªããŸããã³ãŒã«ããã¯å°çããããã¹ãã§ãŒã³ã¯ã³ã³ããã¹ãã®æµããäžæçã«ããã¡ã³ããã³ã¹ã®åé¡ãæœåšçãªã»ãã¥ãªãã£è匱æ§ã«ã€ãªããå¯èœæ§ããããŸãããã®ç°¡ç¥åãããäŸãèããŠã¿ãŸãããïŒ
function processRequest(req, res) {
const userId = req.userId;
fetchData(userId, (data) => {
transformData(userId, data, (transformedData) => {
logData(userId, transformedData, () => {
res.send(transformedData);
});
});
});
}
ãã®äŸã§ã¯ãuserId
ããã¹ããããã³ãŒã«ããã¯ãéããŠç¹°ãè¿ãæž¡ãããŠããŸãããã®ã¢ãããŒãã¯åé·ã§ããã ãã§ãªãã颿°ãå¯çµåãããåå©çšæ§ãäœäžããããã¹ããå°é£ã«ããŸãã
AsyncLocalStorageã®å°å ¥
AsyncLocalStorage
ã¯Node.jsã®çµã¿èŸŒã¿ã¢ãžã¥ãŒã«ã§ãç¹å®ã®éåæã³ã³ããã¹ãã«ããŒã«ã«ãªããŒã¿ãä¿åããã¡ã«ããºã ãæäŸããŸããããã«ãããåãå®è¡ã³ã³ããã¹ãå
ã®éåæå¢çãè¶ããŠèªåçã«äŒæãããå€ãèšå®ããã³ååŸã§ããŸããããã¯ããªã¯ãšã¹ãã¹ã³ãŒã倿°ã®ç®¡çã倧å¹
ã«ç°¡çŽ åããŸãã
AsyncLocalStorageã®ä»çµã¿
AsyncLocalStorage
ã¯ãçŸåšã®éåææäœã«é¢é£ä»ããããã¹ãã¬ãŒãžã³ã³ããã¹ããäœæããããšã§æ©èœããŸããæ°ããéåææäœïŒäŸïŒãããã¹ãã³ãŒã«ããã¯ïŒãéå§ããããšãã¹ãã¬ãŒãžã³ã³ããã¹ãã¯èªåçã«æ°ããæäœã«äŒæãããŸããããã«ãããéåæåŒã³åºãã®ãã§ãŒã³å
šäœãéããŠåãããŒã¿ã«ã¢ã¯ã»ã¹ã§ããããšãä¿èšŒãããŸãã
AsyncLocalStorageã®åºæ¬çãªäœ¿ãæ¹
以äžã¯ãAsyncLocalStorage
ã䜿çšããæ¹æ³ã®åºæ¬çãªäŸã§ãïŒ
const { AsyncLocalStorage } = require('async_hooks');
const asyncLocalStorage = new AsyncLocalStorage();
function processRequest(req, res) {
const userId = req.userId;
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('userId', userId);
fetchData().then(data => {
return transformData(data);
}).then(transformedData => {
return logData(transformedData);
}).then(() => {
res.send(transformedData);
});
});
}
async function fetchData() {
const userId = asyncLocalStorage.getStore().get('userId');
// ... fetch data using userId
return data;
}
async function transformData(data) {
const userId = asyncLocalStorage.getStore().get('userId');
// ... transform data using userId
return transformedData;
}
async function logData(data) {
const userId = asyncLocalStorage.getStore().get('userId');
// ... log data using userId
return;
}
ãã®äŸã§ã¯ïŒ
AsyncLocalStorage
ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããŸããprocessRequest
颿°å ã§ãasyncLocalStorage.run
ã䜿çšããŠãæ°ããã¹ãã¬ãŒãžã€ã³ã¹ã¿ã³ã¹ïŒãã®å Žåã¯Map
ïŒã®ã³ã³ããã¹ãå ã§é¢æ°ãå®è¡ããŸããasyncLocalStorage.getStore().set('userId', userId)
ã䜿çšããŠãã¹ãã¬ãŒãžã«userId
ãèšå®ããŸãã- éåææäœïŒ
fetchData
ãtransformData
ãlogData
ïŒå ã§ãasyncLocalStorage.getStore().get('userId')
ã䜿çšããŠuserId
ãååŸã§ããŸãã
AsyncLocalStorageã®ãŠãŒã¹ã±ãŒã¹
AsyncLocalStorage
ã¯ãç¹ã«ä»¥äžã®ã·ããªãªã§åœ¹ç«ã¡ãŸãïŒ
1. ãªã¯ãšã¹ããã¬ãŒã·ã³ã°
忣ã·ã¹ãã ã§ã¯ãè€æ°ã®ãµãŒãã¹ã«ãŸããããªã¯ãšã¹ãã远跡ããããšã¯ãããã©ãŒãã³ã¹ã®ç£èŠãšããã«ããã¯ã®ç¹å®ã«äžå¯æ¬ ã§ããAsyncLocalStorage
ã䜿çšããŠããµãŒãã¹å¢çãè¶ããŠäŒæãããäžæã®ãªã¯ãšã¹ãIDãä¿åã§ããŸããããã«ãããç°ãªããµãŒãã¹ããã®ãã°ãšã¡ããªã¯ã¹ãçžé¢ããããªã¯ãšã¹ãã®å
šäœåãå
æ¬çã«ææ¡ã§ããŸããäŸãã°ããŠãŒã¶ãŒãªã¯ãšã¹ããAPIã²ãŒããŠã§ã€ãèªèšŒãµãŒãã¹ãããŒã¿åŠçãµãŒãã¹ãééãããã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ãèããŠã¿ãŸããããAsyncLocalStorage
ã䜿çšãããšãAPIã²ãŒããŠã§ã€ã§äžæã®ãªã¯ãšã¹ãIDãçæããããªã¯ãšã¹ãã®åŠçã«é¢äžããåŸç¶ã®ãã¹ãŠã®ãµãŒãã¹ã«èªåçã«äŒæãããŸãã
2. ãã®ã³ã°ã³ã³ããã¹ã
ã€ãã³ãããã®ã³ã°ããéããŠãŒã¶ãŒIDããªã¯ãšã¹ãIDãã»ãã·ã§ã³IDãªã©ã®ã³ã³ããã¹ãæ
å ±ãå«ãããšäŸ¿å©ãªããšããããããŸããAsyncLocalStorage
ã䜿çšãããšããããã®æ
å ±ããã°ã¡ãã»ãŒãžã«èªåçã«å«ããããšãã§ããåé¡ã®ãããã°ãšåæã容æã«ãªããŸããã¢ããªã±ãŒã·ã§ã³å
ã§ã®ãŠãŒã¶ãŒã¢ã¯ãã£ããã£ã远跡ããå¿
èŠãããã·ããªãªãæ³åããŠã¿ãŠãã ãããAsyncLocalStorage
ã«ãŠãŒã¶ãŒIDãä¿åããããšã§ããã®ãŠãŒã¶ãŒã®ã»ãã·ã§ã³ã«é¢é£ãããã¹ãŠã®ãã°ã¡ãã»ãŒãžã«èªåçã«IDãå«ããããšãã§ãããŠãŒã¶ãŒã®è¡åãééããŠããå¯èœæ§ã®ããåé¡ã«é¢ãã貎éãªæŽå¯ãæäŸããŸãã
3. èªèšŒãšèªå¯
AsyncLocalStorage
ã¯ããŠãŒã¶ãŒã®ããŒã«ãæš©éãªã©ã®èªèšŒã»èªå¯æ
å ±ãä¿åããããã«äœ¿çšã§ããŸããããã«ããããŠãŒã¶ãŒã®è³æ Œæ
å ±ããã¹ãŠã®é¢æ°ã«æç€ºçã«æž¡ãããšãªããã¢ããªã±ãŒã·ã§ã³å
šäœã§ã¢ã¯ã»ã¹å¶åŸ¡ããªã·ãŒã匷å¶ã§ããŸããäŸãã°ãç°ãªããŠãŒã¶ãŒãç°ãªãã¢ã¯ã»ã¹ã¬ãã«ïŒäŸïŒç®¡çè
ãäžè¬é¡§å®¢ïŒãæã€eã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãèããŠã¿ãŸããããAsyncLocalStorage
ã«ãŠãŒã¶ãŒã®ããŒã«ãä¿åããããšã§ãç¹å®ã®æäœãå®è¡ããåã«ãŠãŒã¶ãŒã®æš©éãç°¡åã«ç¢ºèªã§ããèªå¯ããããŠãŒã¶ãŒã®ã¿ãæ©å¯ããŒã¿ãæ©èœã«ã¢ã¯ã»ã¹ã§ããããã«ä¿èšŒããŸãã
4. ããŒã¿ããŒã¹ãã©ã³ã¶ã¯ã·ã§ã³
ããŒã¿ããŒã¹ãæ±ãéãè€æ°ã®éåææäœã«ããã£ãŠãã©ã³ã¶ã¯ã·ã§ã³ã管çããå¿
èŠããã°ãã°ãããŸããAsyncLocalStorage
ã䜿çšããŠããŒã¿ããŒã¹æ¥ç¶ãŸãã¯ãã©ã³ã¶ã¯ã·ã§ã³ãªããžã§ã¯ããä¿åããåããªã¯ãšã¹ãå
ã®ãã¹ãŠã®æäœãåããã©ã³ã¶ã¯ã·ã§ã³å
ã§å®è¡ãããããã«ä¿èšŒã§ããŸããäŸãã°ããŠãŒã¶ãŒã泚æãè¡ãå Žåãè€æ°ã®ããŒãã«ïŒäŸïŒordersãorder_itemsãinventoryïŒãæŽæ°ããå¿
èŠããããããããŸãããããŒã¿ããŒã¹ãã©ã³ã¶ã¯ã·ã§ã³ãªããžã§ã¯ããAsyncLocalStorage
ã«ä¿åããããšã§ãããããã¹ãŠã®æŽæ°ãåäžã®ãã©ã³ã¶ã¯ã·ã§ã³å
ã§å®è¡ãããããšãä¿èšŒããååæ§ãšäžè²«æ§ãæ
ä¿ããŸãã
5. ãã«ãããã³ã·ãŒ
ãã«ãããã³ãã¢ããªã±ãŒã·ã§ã³ã§ã¯ãåããã³ãã®ããŒã¿ãšãªãœãŒã¹ãåé¢ããããšãäžå¯æ¬ ã§ããAsyncLocalStorage
ã䜿çšããŠããã³ãIDãä¿åããçŸåšã®ããã³ãã«åºã¥ããŠãªã¯ãšã¹ããé©åãªããŒã¿ã¹ãã¢ãŸãã¯ãªãœãŒã¹ã«åçã«ã«ãŒãã£ã³ã°ã§ããŸããè€æ°ã®çµç¹ãåãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ã䜿çšããSaaSãã©ãããã©ãŒã ãæ³åããŠã¿ãŠãã ãããAsyncLocalStorage
ã«ããã³ãIDãä¿åããããšã§ãåçµç¹ã®ããŒã¿ãåé¢ãããèªåãã¡ã®ãªãœãŒã¹ã«ã®ã¿ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã
AsyncLocalStorageã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹
AsyncLocalStorage
ã¯åŒ·åãªããŒã«ã§ãããæœåšçãªããã©ãŒãã³ã¹ã®åé¡ãé¿ããã³ãŒãã®æçããç¶æããããã«ãæ
éã«äœ¿çšããããšãéèŠã§ãã以äžã«çæãã¹ããã¹ããã©ã¯ãã£ã¹ãããã€ã瀺ããŸãïŒ
1. ããŒã¿ã¹ãã¬ãŒãžãæå°éã«æãã
AsyncLocalStorage
ã«ã¯çµ¶å¯Ÿã«äžå¯æ¬ ãªããŒã¿ã®ã¿ãä¿åããŠãã ããã倧éã®ããŒã¿ãä¿åãããšãç¹ã«é«äžŠè¡æ§ç°å¢ã§ã¯ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸããäŸãã°ããŠãŒã¶ãŒãªããžã§ã¯ãå
šäœãä¿åãã代ããã«ããŠãŒã¶ãŒIDã®ã¿ãä¿åããå¿
èŠã«å¿ããŠãã£ãã·ã¥ãããŒã¿ããŒã¹ãããŠãŒã¶ãŒãªããžã§ã¯ããååŸããããšãæ€èšããŠãã ããã
2. é床ãªã³ã³ããã¹ãåãæ¿ããé¿ãã
é »ç¹ãªã³ã³ããã¹ãåãæ¿ããããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸããAsyncLocalStorage
ããã®å€ã®èšå®ãšååŸã®åæ°ãæå°éã«æããŠãã ãããé »ç¹ã«ã¢ã¯ã»ã¹ãããå€ã¯é¢æ°å
ã§ããŒã«ã«ã«ãã£ãã·ã¥ããã¹ãã¬ãŒãžã³ã³ããã¹ããžã®ã¢ã¯ã»ã¹ã®ãªãŒããŒããããåæžããŸããäŸãã°ã颿°å
ã§ãŠãŒã¶ãŒIDã«è€æ°åã¢ã¯ã»ã¹ããå¿
èŠãããå ŽåãäžåºŠAsyncLocalStorage
ããååŸãããã®åŸã®äœ¿çšã®ããã«ããŒã«ã«å€æ°ã«ä¿åããŸãã
3. æç¢ºã§äžè²«æ§ã®ããåœåèŠåã䜿çšãã
AsyncLocalStorage
ã«ä¿åããããŒã«ã¯ãæç¢ºã§äžè²«æ§ã®ããåœåèŠåã䜿çšããŠãã ãããããã«ãããã³ãŒãã®å¯èªæ§ãšä¿å®æ§ãåäžããŸããäŸãã°ãrequest.id
ãuser.id
ã®ããã«ãç¹å®ã®æ©èœããã¡ã€ã³ã«é¢é£ãããã¹ãŠã®ããŒã«äžè²«ãããã¬ãã£ãã¯ã¹ã䜿çšããŸãã
4. 䜿çšåŸã¯ã¯ãªãŒã³ã¢ãããã
AsyncLocalStorage
ã¯éåææäœãå®äºãããšèªåçã«ã¹ãã¬ãŒãžã³ã³ããã¹ããã¯ãªãŒã³ã¢ããããŸãããäžèŠã«ãªã£ããšãã«æç€ºçã«ã¹ãã¬ãŒãžã³ã³ããã¹ããã¯ãªã¢ããããšã¯è¯ãç¿æ
£ã§ããããã«ãããã¡ã¢ãªãªãŒã¯ãé²ããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸããããã¯exit
ã¡ãœããã䜿çšããŠã³ã³ããã¹ããæç€ºçã«ã¯ãªã¢ããããšã§å®çŸã§ããŸãã
5. ããã©ãŒãã³ã¹ãžã®åœ±é¿ãèæ ®ãã
ç¹ã«é«äžŠè¡æ§ç°å¢ã«ãããŠãAsyncLocalStorage
ã䜿çšããããšã«ããããã©ãŒãã³ã¹ãžã®åœ±é¿ãèªèããŠãã ãããã³ãŒãããã³ãããŒã¯ããŠãããã©ãŒãã³ã¹èŠä»¶ãæºãããŠããããšã確èªããŸããã¢ããªã±ãŒã·ã§ã³ããããã¡ã€ãªã³ã°ããŠãã³ã³ããã¹ã管çã«é¢é£ããæœåšçãªããã«ããã¯ãç¹å®ããŸããAsyncLocalStorage
ã蚱容ã§ããªãããã©ãŒãã³ã¹ãªãŒããŒããããããããå Žåã¯ãæç€ºçãªã³ã³ããã¹ãæž¡ããªã©ã®ä»£æ¿ã¢ãããŒããæ€èšããŠãã ããã
6. ã©ã€ãã©ãªã§ã®äœ¿çšã«ã¯æ³šæãã
æ±çšçãªäœ¿çšãæå³ããã©ã€ãã©ãªã§AsyncLocalStorage
ãçŽæ¥äœ¿çšããããšã¯é¿ããŠãã ãããã©ã€ãã©ãªã¯ãããã䜿çšãããã³ã³ããã¹ãã«ã€ããŠä»®å®ããã¹ãã§ã¯ãããŸããã代ããã«ããŠãŒã¶ãŒãã³ã³ããã¹ãæ
å ±ãæç€ºçã«æž¡ãããã®ãªãã·ã§ã³ãæäŸããŸããããã«ããããŠãŒã¶ãŒã¯èªåã®ã¢ããªã±ãŒã·ã§ã³ã§ã³ã³ããã¹ããã©ã®ããã«ç®¡çãããããå¶åŸ¡ã§ããæœåšçãªç«¶åãäºæããªãåäœãåé¿ã§ããŸãã
AsyncLocalStorageã®ä»£æ¿ææ®µ
AsyncLocalStorage
ã¯äŸ¿å©ã§åŒ·åãªããŒã«ã§ããããã¹ãŠã®ã·ããªãªã§åžžã«æé©ãªè§£æ±ºçã§ãããšã¯éããŸããã以äžã«æ€èšãã¹ãä»£æ¿ææ®µãããã€ã瀺ããŸãïŒ
1. æç€ºçãªã³ã³ããã¹ãæž¡ã
æãåçŽãªã¢ãããŒãã¯ãã³ã³ããã¹ãæ å ±ã颿°ã®åŒæ°ãšããŠæç€ºçã«æž¡ãããšã§ãããã®ã¢ãããŒãã¯çŽæ¥çã§çè§£ããããã§ãããã³ãŒãã®è€éããå¢ãã«ã€ããŠç ©éã«ãªãå¯èœæ§ããããŸããæç€ºçãªã³ã³ããã¹ãæž¡ãã¯ãã³ã³ããã¹ããæ¯èŒçå°ãããã³ãŒããæ·±ããã¹ããããŠããªãåçŽãªã·ããªãªã«é©ããŠããŸããããããããè€éãªã·ããªãªã§ã¯ãèªã¿ã«ããä¿å®ãå°é£ãªã³ãŒãã«ã€ãªããå¯èœæ§ããããŸãã
2. ã³ã³ããã¹ããªããžã§ã¯ã
åã
ã®å€æ°ãæž¡ã代ããã«ããã¹ãŠã®ã³ã³ããã¹ãæ
å ±ãã«ãã»ã«åããã³ã³ããã¹ããªããžã§ã¯ããäœæã§ããŸããããã«ããã颿°ã®ã·ã°ããã£ãç°¡çŽ åãããã³ãŒããããèªã¿ããããªããŸããã³ã³ããã¹ããªããžã§ã¯ãã¯ãæç€ºçãªã³ã³ããã¹ãæž¡ããšAsyncLocalStorage
ã®äžéçãªè¯ã劥åç¹ã§ããé¢é£ããã³ã³ããã¹ãæ
å ±ããŸãšããŠã°ã«ãŒãåããæ¹æ³ãæäŸããã³ãŒããããæŽçãããçè§£ããããããŸããããããå颿°ã«ã³ã³ããã¹ããªããžã§ã¯ããæç€ºçã«æž¡ãå¿
èŠã¯äŸç¶ãšããŠãããŸãã
3. Async HooksïŒèšºæçšïŒ
Node.jsã®async_hooks
ã¢ãžã¥ãŒã«ã¯ãéåææäœã远跡ããããã®ããäžè¬çãªã¡ã«ããºã ãæäŸããŸããAsyncLocalStorage
ããã䜿çšãè€éã§ãããããé«ãæè»æ§ãšå¶åŸ¡ãæäŸããŸããasync_hooks
ã¯äž»ã«èšºæãšãããã°ãç®çãšããŠããŸããéåææäœã®ã©ã€ããµã€ã¯ã«ã远跡ãããã®å®è¡ã«é¢ããæ
å ±ãåéã§ããŸãããã ããæœåšçãªããã©ãŒãã³ã¹ãªãŒããŒãããã®ãããæ±çšçãªã³ã³ããã¹ã管çã«ã¯æšå¥šãããŸããã
4. 蚺æã³ã³ããã¹ã (OpenTelemetry)
OpenTelemetryã¯ããã¬ãŒã¹ãã¡ããªã¯ã¹ããã°ãå«ããã¬ã¡ããªããŒã¿ãåéããã³ãšã¯ã¹ããŒãããããã®æšæºåãããAPIãæäŸããŸãããã®èšºæã³ã³ããã¹ãæ©èœã¯ã忣ã·ã¹ãã ã«ãããã³ã³ããã¹ãäŒæã管çããããã®é«åºŠã§å ç¢ãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸããOpenTelemetryãšçµ±åããããšã§ãç°ãªããµãŒãã¹ããã©ãããã©ãŒã éã§ã³ã³ããã¹ãã®äžè²«æ§ã確ä¿ãããã³ããŒãã¥ãŒãã©ã«ãªæ¹æ³ãæäŸãããŸããããã¯ãã³ã³ããã¹ãããµãŒãã¹å¢çãè¶ããŠäŒæãããå¿ èŠãããè€éãªãã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ã§ç¹ã«æçšã§ãã
å®äžçã§ã®äŸ
AsyncLocalStorage
ãããŸããŸãªã·ããªãªã§ã©ã®ããã«äœ¿çšã§ããããããã€ãã®å®äŸãæ¢ã£ãŠã¿ãŸãããã
1. Eã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ïŒãªã¯ãšã¹ããã¬ãŒã·ã³ã°
eã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãAsyncLocalStorage
ã䜿çšããŠãååã«ã¿ãã°ãã·ã§ããã³ã°ã«ãŒããæ¯æãã²ãŒããŠã§ã€ãªã©ã®è€æ°ã®ãµãŒãã¹ã«ãŸããããŠãŒã¶ãŒãªã¯ãšã¹ãã远跡ã§ããŸããããã«ãããåãµãŒãã¹ã®ããã©ãŒãã³ã¹ãç£èŠãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã«åœ±é¿ãäžããŠããå¯èœæ§ã®ããããã«ããã¯ãç¹å®ã§ããŸãã
// APIã²ãŒããŠã§ã€ã«ãŠ
const { AsyncLocalStorage } = require('async_hooks');
const { v4: uuidv4 } = require('uuid');
const asyncLocalStorage = new AsyncLocalStorage();
app.use((req, res, next) => {
const requestId = uuidv4();
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('requestId', requestId);
res.setHeader('X-Request-Id', requestId);
next();
});
});
// ååã«ã¿ãã°ãµãŒãã¹ã«ãŠ
async function getProductDetails(productId) {
const requestId = asyncLocalStorage.getStore().get('requestId');
// ãªã¯ãšã¹ãIDãä»ã®è©³çްãšå
±ã«ãã°ã«èšé²
logger.info(`[${requestId}] Fetching product details for product ID: ${productId}`);
// ... åå詳现ãååŸ
}
2. SaaSãã©ãããã©ãŒã ïŒãã«ãããã³ã·ãŒ
SaaSãã©ãããã©ãŒã ã§ã¯ãAsyncLocalStorage
ã䜿çšããŠããã³ãIDãä¿åããçŸåšã®ããã³ãã«åºã¥ããŠãªã¯ãšã¹ããé©åãªããŒã¿ã¹ãã¢ãŸãã¯ãªãœãŒã¹ã«åçã«ã«ãŒãã£ã³ã°ã§ããŸããããã«ãããåããã³ãã®ããŒã¿ãåé¢ãããèªåãã¡ã®ãªãœãŒã¹ã«ã®ã¿ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã
// ãªã¯ãšã¹ãããããã³ãIDãæœåºããããã«ãŠã§ã¢
app.use((req, res, next) => {
const tenantId = req.headers['x-tenant-id'];
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('tenantId', tenantId);
next();
});
});
// ç¹å®ã®ããã³ãã®ããŒã¿ãååŸãã颿°
async function fetchData(query) {
const tenantId = asyncLocalStorage.getStore().get('tenantId');
const db = getDatabaseConnection(tenantId);
return db.query(query);
}
3. ãã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ïŒãã®ã³ã°ã³ã³ããã¹ã
ãã€ã¯ããµãŒãã¹ã¢ãŒããã¯ãã£ã§ã¯ãAsyncLocalStorage
ã䜿çšããŠãŠãŒã¶ãŒIDãä¿åããç°ãªããµãŒãã¹ããã®ãã°ã¡ãã»ãŒãžã«èªåçã«å«ããããšãã§ããŸããããã«ãããç¹å®ã®ãŠãŒã¶ãŒã«åœ±é¿ãäžããŠããå¯èœæ§ã®ããåé¡ããããã°ããã³åæãããããªããŸãã
// èªèšŒãµãŒãã¹ã«ãŠ
app.use((req, res, next) => {
const userId = req.user.id;
asyncLocalStorage.run(new Map(), () => {
asyncLocalStorage.getStore().set('userId', userId);
next();
});
});
// ããŒã¿åŠçãµãŒãã¹ã«ãŠ
async function processData(data) {
const userId = asyncLocalStorage.getStore().get('userId');
logger.info(`[User ID: ${userId}] Processing data: ${JSON.stringify(data)}`);
// ... ããŒã¿ãåŠç
}
çµè«
AsyncLocalStorage
ã¯ãéåæJavaScriptç°å¢ã§ãªã¯ãšã¹ãã¹ã³ãŒã倿°ã管çããããã®è²ŽéãªããŒã«ã§ããéåææäœããŸããã ã³ã³ããã¹ãã®ç®¡çãç°¡çŽ åããã³ãŒããããèªã¿ããããä¿å®ãããããå®å
šã«ããŸãããã®ãŠãŒã¹ã±ãŒã¹ããã¹ããã©ã¯ãã£ã¹ãããã³ä»£æ¿ææ®µãçè§£ããããšã§ãå
ç¢ã§ã¹ã±ãŒã©ãã«ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«AsyncLocalStorage
ã广çã«æŽ»çšã§ããŸãããã ããããã©ãŒãã³ã¹ãžã®åœ±é¿ãæ
éã«æ€èšããæœåšçãªåé¡ãé¿ããããã«è³¢æã«äœ¿çšããããšãéèŠã§ããéåæJavaScriptéçºã®å®è·µãåäžãããããã«ãAsyncLocalStorage
ãææ
®æ·±ãæ¡çšããŠãã ããã
æç¢ºãªäŸãå®è·µçãªã¢ããã€ã¹ããããŠå
æ¬çãªæŠèŠãçµã¿èŸŒãããšã§ããã®ã¬ã€ãã¯äžçäžã®éçºè
ãJavaScriptã¢ããªã±ãŒã·ã§ã³ã§AsyncLocalStorage
ã䜿çšããŠéåæã³ã³ããã¹ãã广çã«ç®¡çããããã®ç¥èã身ã«ã€ããããšãç®çãšããŠããŸããç¹å®ã®ããŒãºã«æé©ãªãœãªã¥ãŒã·ã§ã³ã確ä¿ããããã«ãããã©ãŒãã³ã¹ãžã®åœ±é¿ãšä»£æ¿ææ®µãèæ
®ããããšãå¿ããªãã§ãã ããã